#include "stdafx.h"
#include "WatchViewOneVar.h"
#include "VariableWatch.h"
#include <wx/sizer.h>

LUA_DEBUG_BEGIN

BEGIN_EVENT_TABLE(OneVariableWatchView, wxFrame)
EVT_MOTION(OneVariableWatchView::OnMotion)
END_EVENT_TABLE()

/*-----------------------------------------------------------------*/
/**
* @brief 
*/
struct OneVariableWatchView::CallbackHandler
{
    explicit CallbackHandler(VariableWatch *watch,const LuaVarListCallback &callback)
        : m_watch(watch), m_callback(callback)
    {
    }
    int operator()(const LuaCommand &command, const LuaVarList &vars) {
        if (m_callback(command, vars) != 0) {
            return -1;
        }

        // Expand the item, if it has some children.
        wxTreeItemIdValue cookie;
        wxTreeItemId item = m_watch->GetFirstChild(m_watch->GetRootItem(), cookie);
        if (item.IsOk()) {
            m_watch->Expand(item);
        }
        return 0;
    }
private:
    VariableWatch *m_watch;
    LuaVarListCallback m_callback;
};

/**
* @brief Request for the evalution of one value.
*/
struct OneVariableWatchView::VariableRequester
{
    explicit VariableRequester(Mediator_ptr mediator,VariableWatch **watch,const wxString &valName)
        : m_mediator(mediator),m_watch(watch)
    {
        //m_valNameUTF8 = wxConvToCtxEnc(valName);
        m_valNameUTF8 = valName;
    }
    void operator()(const LuaVarListCallback &callback)
    {
        m_mediator->GetEngine()->SendEvalToMultiVar("return " + m_valNameUTF8,
        	m_mediator->GetStackFrame(),CallbackHandler(*m_watch, callback));
    }
private:
    Mediator_ptr m_mediator;
    VariableWatch **m_watch;
    std::string m_valNameUTF8;
};

OneVariableWatchView::OneVariableWatchView(Mediator_ptr mediator,
                                           wxWindow *parent,
                                           const wxString &valName,
                                           const wxPoint &pos,
                                           const wxSize &size) :
wxFrame(parent, wxID_ANY, _T(""), pos, size, wxFRAME_TOOL_WINDOW | wxRESIZE_BORDER /*| wxFRAME_NO_TASKBAR*/ | wxFRAME_FLOAT_ON_PARENT),
m_mediator(mediator),
m_wasInMouse(false)
{
    VariableWatch *watch = NULL;
    watch = new VariableWatch(m_mediator,this, wxID_ANY,true, true, false, true,
        VariableRequester(m_mediator, &watch, valName));

    // Add the name of the variable.
    watch->AppendItem(watch->GetRootItem(), valName, -1, -1,
        new VariableWatchItemData(m_mediator,LuaVar()));
    watch->BeginUpdating();
    //SetHandler(watch); // Set handler to receive the mouse event.
    m_watch = watch;

    wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
    sizer->Add(watch, 1, wxEXPAND);
    SetSizer(sizer);
    sizer->SetSizeHints(this);
}

OneVariableWatchView::~OneVariableWatchView() {
}

void OneVariableWatchView::SetHandler(wxWindow *target) {
    if (target == NULL) {
        return;
    }

    // Set the handler.
    target->SetNextHandler(this->GetEventHandler());

    // Set the handler to the children.
    wxWindowList children = target->GetChildren();
    for (size_t i = 0; i < children.GetCount(); ++i) {
        SetHandler(children[i]);
    }
}

void OneVariableWatchView::OnMotion(wxMouseEvent &event) {
    event.Skip();
    m_wasInMouse = true;
}

LUA_DEBUG_END
